//
//  VVRefreshControl.swift
//  Weibo
//
//  Created by 王惠平 on 2017/4/2.
//  Copyright © 2017年 Will Wang. All rights reserved.
//

import UIKit

//自定义控件的高度
private let VVRefreshControlHeight:CGFloat = 50

//自定义下拉刷新状态
enum VVRefreshControlType {
    
    //下拉刷新
    case normal

    //松手刷新
    case pulling
    
    //正在刷新
    case refreshing
}

class VVRefreshControl: UIControl {
    
    //懒加载控件
    //默认是下拉刷新状态
    var refreshType: VVRefreshControlType = .normal {
        
        didSet{
            
            switch refreshType {
            
            case .normal:
                
                //箭头显示
                pullDownImageView.isHidden = false
                
                //关闭风火轮
                indicatorView.stopAnimating()
                
                //文字改成下拉刷新
                messageLabel.text = "下拉刷新"
                
                UIView.animate(withDuration: 0.25, animations: { 
                    
                    //箭头重置
                    self.pullDownImageView.transform = CGAffineTransform.identity
                    
                })
                
                //只有上一次是正在刷新是让其重置,隐藏会原来位置oldValue表示上一次保存的值
                if oldValue == .refreshing {
                    
                    UIView.animate(withDuration: 0.25, animations: { 
                        
                        //重置原始的显示内容
                        self.currentScrollView?.contentInset.top -= VVRefreshControlHeight
                    })
                }
                
            case .pulling:
                
                //箭头调转,文字改成松开刷新
                UIView.animate(withDuration: 0.25, animations: {
                    
                    self.pullDownImageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
                    
                })
                
                messageLabel.text = "松开刷新"
                
                
            case .refreshing:
                
                //箭头隐藏
                pullDownImageView.isHidden = true
                
                //开启风火轮
                indicatorView.startAnimating()
                
                //文字改成正在熟悉
                messageLabel.text = "正在刷新.."
                
                UIView.animate(withDuration: 0.25, animations: { 
                    
                    //设置停留.把内容区域放大
                    self.currentScrollView?.contentInset.top += VVRefreshControlHeight
                    
                }, completion: {(_) in
                    
                    //通知外面刷新数据,主动发送事件
                    self.sendActions(for: .valueChanged)
                    
                })
                
            }
        }

    }
    
    //记录当前滚动色视图
    var currentScrollView: UIScrollView?
    
    //下拉箭头
    fileprivate lazy var pullDownImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))

    //风火轮
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    
    //消息labl
    fileprivate lazy var messageLabel: UILabel = {
        
       let label = UILabel()
        
        label.text = "下拉刷新"
        
        label.font = UIFont.systemFont(ofSize: 12)
        
        label.textColor = UIColor.gray
        
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
   fileprivate func setupUI() {
        
    backgroundColor = UIColor.red
    
    //添加子控件
    addSubview(pullDownImageView)
    addSubview(messageLabel)
    addSubview(indicatorView)
    
    //使用手写代码完成自动布局
    pullDownImageView.translatesAutoresizingMaskIntoConstraints = false
    indicatorView.translatesAutoresizingMaskIntoConstraints = false
    messageLabel.translatesAutoresizingMaskIntoConstraints = false
    
    //添加约束
    addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
    addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    
    addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: pullDownImageView, attribute: .centerY, multiplier: 1, constant: 0))
    addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: pullDownImageView, attribute: .centerX, multiplier: 1, constant: 0))
    
    addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: indicatorView, attribute: .trailing, multiplier: 1, constant: 10))
    addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem:self , attribute: .centerY, multiplier: 1, constant: 0))
    
    //开启风火轮
    //indicatorView.startAnimating()
        
    }
    
    //将要添加到父视图上会执行这个方法
    override func willMove(toSuperview newSuperview: UIView?) {
        
        //判断父视图是否是UIScrollview的子类
        guard let scrollView = newSuperview as? UIScrollView else {
            
            return
        }
        
        //设置大小
        self.frame.size = CGSize(width: scrollView.frame.size.width, height: VVRefreshControlHeight)
        
        //修改y坐标
        self.frame.origin.y = -VVRefreshControlHeight
        
        //引入kvo监听属性值的改变,使用当前对象监听属性值的改变就是kvo
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        
        //记录滚动视图
        currentScrollView = scrollView
    
    }
    
    //kvo监听方法 只要contentOffset这个发生改变就会回调这个方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        //print(currentScrollView?.contentOffset.y ?? 0)
        
        //滚动的偏移量
        let contentOffsetY = currentScrollView!.contentOffset.y
        
        //计算拖动的临界点
        //currentScrollView?.contentInset.top 表示内容显示的位置距离顶部的距离
        let limitY = -((currentScrollView?.contentInset.top)! + VVRefreshControlHeight)
        
        if (currentScrollView?.isDragging)! {
            
            //拖动情况下有normal状态进入pulling
            if contentOffsetY < limitY && refreshType == .normal {
                
                print("松开刷新")
                refreshType = .pulling
                
            } else if refreshType == .pulling && contentOffsetY >= limitY {
                
                print("下拉刷新")
                refreshType = .normal
                
            }
        
        } else {
            
            //正在刷新 1.松手 2.刷新的状态必须pulling
            if refreshType == .pulling {
                
                print("正在刷新...")
                refreshType = .refreshing
                
            }
            
            
        }
        
    }
    
    //结束刷新
    func endRefreshing() {
        
        //状态重置
        refreshType = .normal
    }
    
    //析构函数
    deinit {
        
        //移除kvo
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }

}
